type ChineseNumberStyle = 'modern' | 'traditional';
type ConversionType = 'literal' | 'verbal' | 'money';

interface Options {
    textType: ChineseNumberStyle;
    semanticType: ConversionType;
}

interface ChineseNumberMap {
    modern: Record<string, string>;
    traditional: Record<string, string>;
}

const chineseNumberMap: ChineseNumberMap = {
    modern: {
        '0': '零',
        '1': '一',
        '2': '二',
        '3': '三',
        '4': '四',
        '5': '五',
        '6': '六',
        '7': '七',
        '8': '八',
        '9': '九'
    },
    traditional: {
        '0': '零',
        '1': '壹',
        '2': '贰',
        '3': '叁',
        '4': '肆',
        '5': '伍',
        '6': '陆',
        '7': '柒',
        '8': '捌',
        '9': '玖'
    }
};

const moneyUnits = ['角', '分', '厘', '毫', '微', '纳', '皮'];
const integerUnits_ = ['', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '兆'];
const oldIntegerUnits = ['', '拾', '佰', '仟', '万', '十', '佰', '仟', '亿', '拾', '佰', '仟', '兆'];

export function devNumberToChinese(
    num: number,
    options: Options = {textType: 'modern', semanticType: 'verbal'}
): string {
    if (typeof num !== 'number' || isNaN(num) || (num !== 0 && !num)) return'';

    const {textType, semanticType} = options;
    const integerUnits = textType === 'modern' ? integerUnits_ : oldIntegerUnits;

    const digitsMap = chineseNumberMap[textType];
    const numStr = num.toString();
    const [integerPart, decimalPart] = numStr.includes('.') ? numStr.split('.') : [numStr, ''];

    // 字面转换（literal）：简单逐位映射
    function convertLiteral(integer: string, decimal: string): string {
        const integerStr = [...integer].map(digit => digitsMap[digit]).join('');
        const decimalStr = decimal ? `点${[...decimal].map(d => digitsMap[d]).join('')}` : '';
        return integerStr + decimalStr;
    }

    // 口语化转换（verbal）：按自然数规则表达
    function convertIntegerVerbal(integer: string): string {
        let result = '';
        let zeroFlag = false;

        for (let i = 0; i < integer.length; i++) {
            const digit = parseInt(integer[i]);
            const position = integer.length - i - 1;
            const unit = integerUnits[position % 4] || '';
            const sectionUnit = position >= 4 ? integerUnits[4 * Math.floor(position / 4)] : '';

            if (digit === 0) {
                zeroFlag = true;
            } else {
                if (zeroFlag) {
                    result += digitsMap['0'];
                    zeroFlag = false;
                }
                result += digitsMap[digit] + unit;
            }

            if (position % 4 === 0 && result[result.length - 1] !== sectionUnit) {
                result += sectionUnit;
            }
        }

        return result.replace(/零+$/, '').replace(/零+/g, '零').replace(/^一十/, '十');
    }

    // 金额格式转换（money）：遵循人民币表达
    function convertMoney(integer: string, decimal: string): string {
        let integerStr = '';
        let zeroCount = 0;

        // 特殊情况处理：零元
        if (parseInt(integer) === 0) {
            return '零元' + (decimal ? decimal.replace(/0+$/, '').replace(/^(\d)$/, digitsMap['$1']) : '整');
        }

        for (let i = 0; i < integer.length; i++) {
            const digit = parseInt(integer[i]);
            const position = integer.length - i - 1;
            const unit = integerUnits[position % 4] || '';
            const sectionUnit = position >= 4 ? integerUnits[4 * Math.floor(position / 4)] : '';

            if (digit === 0) {
                zeroCount++;
            } else {
                if (zeroCount > 0) {
                    integerStr += digitsMap['0'];
                    zeroCount = 0;
                }
                integerStr += digitsMap[digit] + unit;
            }

            if (position % 4 === 0 && integerStr[integerStr.length - 1] !== sectionUnit) {
                integerStr += sectionUnit;
            }
        }

        integerStr = integerStr.replace(/零+元$/, '元').replace(/零+$/, '').replace(/^一十/, '十');
        if (integerStr === '') integerStr = '零元';

        const decimalStr = decimal
            ? decimal
                .split('')
                .map((d, i) => (parseInt(d) !== 0 ? digitsMap[d] + (moneyUnits[i] || '') : ''))
                .join('')
                .replace(/零+$/, '')
            : '';

        return integerStr+ '元' + (decimalStr ? decimalStr : '整');
    }

    // 结果处理
    if (semanticType === 'literal') {
        return convertLiteral(integerPart, decimalPart);
    } else if (semanticType === 'verbal') {
        const integerStr = parseInt(integerPart) > 0 ? convertIntegerVerbal(integerPart) : digitsMap['0'];
        const decimalStr = decimalPart ? `点${[...decimalPart].map(d => digitsMap[d]).join('')}` : '';
        return integerStr + decimalStr;
    } else if (semanticType === 'money') {
        return convertMoney(integerPart, decimalPart);
    } else {
        throw new Error('Invalid conversion type');
    }
}
